import logging
from typing import Optional
from fastapi import APIRouter, Depends, Query, Path
from pydantic import BaseModel, Field
from sqlalchemy import text
from sqlalchemy.engine import create
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session

from commons.BaseResponse import BaseResponse
from commons.PaginationBase import PaginationBase
from datebase import get_db
from utils.EncryptionUtil import oauth2_scheme, EncryptionMiddleware

equipment_fault_router = APIRouter(prefix="/fault/equipmentFault", tags=["故障字典管理"],
                                   dependencies=[Depends(oauth2_scheme)])


class EquipmentFaultSearch(PaginationBase):
    feuipmentid: int = Field(None, description="设备id")
    fdangername: str = Field(None, description="故障名")
    ffaultno: str = Field(None, description="故障编号")


@equipment_fault_router.get("/list", summary="故障字典查询接口")
def list_equipment_fault(search: EquipmentFaultSearch = Query(), db: Session = Depends(get_db)):
    param = {}
    sql = "select count(1) from s_ts_equipment_fault where 1=1"
    if search.fdangername != "":
        sql = sql + " and fdangername like concat('%', :fdangername ,'%')"
        param["fdangername"] = search.fdangername
    if search.feuipmentid != "":
        sql = sql + " and feuipmentid = :feuipmentid "
        param["feuipmentid"] = search.feuipmentid
    if search.ffaultno != "":
        sql = sql + " and ffaultno= :ffaultno "
        param["ffaultno"] = search.ffaultno
    count = db.execute(text(sql), param).scalar()

    param = {}
    sql = "select feuipmentid,ferrorno,fdangername,ffaultno,fprocday,fprocword,fupddate,foperator"
    sql = sql + " from s_ts_equipment_fault where 1=1"
    if search.fdangername != "":
        sql = sql + " and fdangername like concat('%', :fdangername ,'%')"
        param["fdangername"] = search.fdangername
    if search.feuipmentid != "":
        sql = sql + " and feuipmentid = :feuipmentid "
        param["feuipmentid"] = search.feuipmentid
    if search.ffaultno != "":
        sql = sql + " and ffaultno= :ffaultno "
        param["ffaultno"] = search.ffaultno
    if search.order == "desc":
        sql = sql + " order by  feuipmentid,ffaultno desc "
    else:
        sql = sql + " order by feuipmentid,ffaultno "
    sql = sql + " limit :limit offset :offset "
    param["limit"] = search.limit
    param["offset"] = search.offset
    data = db.execute(text(sql), param).fetchall()

    data_list = []
    for key in range(len(data)):
        d1 = {}
        d1['feuipmentid'] = data[key][0]
        d1['ferrorno'] = data[key][1]
        d1['fdangername'] = data[key][2]
        d1['ffaultno'] = data[key][3]
        d1['fprocday'] = data[key][4]
        d1['fprocword'] = data[key][5]
        d1['fupddate'] = data[key][6]
        d1['foperator'] = data[key][7]
        data_list.append(d1)

    info_dict = {"list": data_list, "limit": search.limit, "page": search.pageIndex,
                 "pages": (count + search.limit - 1) // search.limit,
                 "total": count}
    return BaseResponse.success(data=info_dict)


class FaultDictionaryCreate(BaseModel):
    """故障字典新增请求参数"""
    fdangername: str = Field(..., description="故障名称")
    ferrorno: int = Field(..., description="错误编号")
    feuipmentid: int = Field(..., description="设备ID")
    ffaultno: int = Field(..., description="故障编号")
    fprocday: int = Field(..., description="处理天数")
    foperator: str = Field(..., description="操作人")
    fupddate: str = Field(..., description="更新日期(yyyy-MM-dd HH:mm:ss)")
    fprocword: Optional[str] = Field("", description="处理描述")


@equipment_fault_router.post("/create", summary="故障字典新增接口")
def create_equipment_fault(create: FaultDictionaryCreate, db: Session = Depends(get_db)):
    try:
        with db.begin():
            sql = "select feuipmentid from s_ts_equipment_fault where feuipmentid= :feuipmentid and ferrorno= :ferrorno "
            data = db.execute(text(sql), {
                "feuipmentid": create.feuipmentid,
                "ferrorno": create.ferrorno,
            }).fetchall()

            if len(data) > 0:
                return BaseResponse.error(message="编号已存在")
            else:
                sql = "insert into s_ts_equipment_fault(feuipmentid,ferrorno,fdangername,ffaultno,fprocday,fprocword,fupddate,foperator)"
                sql = sql + " values( :feuipmentid , :ferrorno , :fdangername , :ffaultno , :fprocday , :fprocword , :fupddate , :foperator );"
                db.execute(text(sql), {
                    "feuipmentid": create.feuipmentid,
                    "ferrorno": create.ferrorno,
                    "fdangername": create.fdangername,
                    "ffaultno": create.ffaultno,
                    "fprocday": create.fprocday,
                    "fprocword": create.fprocword,
                    "fupddate": create.fupddate,
                    "foperator": create.foperator,
                })
                # 返回
                data = {"feuipmentid": create.feuipmentid
                    , "ferrorno": create.ferrorno
                    , "fdangername": create.fdangername
                    , "fprocday": create.fprocday
                    , "fprocword": create.fprocword
                    , "fupddate": create.fupddate
                    , "foperator": create.foperator
                        }
                return BaseResponse.success(data=data)
    except SQLAlchemyError as e:
        # 发生异常时自动回滚
        db.rollback()
        # 记录错误日志
        logging.error(f"数据库错误: {str(e)}")
        # 返回错误响应
        return BaseResponse.error(message="数据库操作失败")
    except Exception as e:
        db.rollback()
        logging.error(f"未知错误: {str(e)}")
        return BaseResponse.error(message="令牌过期")


@equipment_fault_router.post("/update", summary="故障字典修改接口")
def update_equipment_fault(update: FaultDictionaryCreate, db: Session = Depends(get_db),
                           token: str = Depends(oauth2_scheme)):
    try:
        with db.begin():
            sql = "update s_ts_equipment_fault"
            sql = sql + " set fdangername= :fdangername ,fprocword= :fprocword "
            sql = sql + ",ffaultno= :ffaultno ,fprocday= :fprocday "
            sql = sql + ",fupddate= :fupddate ,foperator= :foperator "
            sql = sql + " where feuipmentid= :feuipmentid  and ferrorno= :ferrorno "
            db.execute(text(sql), {
                "feuipmentid": update.feuipmentid,
                "fdangername": update.fdangername,
                "fprocword": update.fprocword,
                "ffaultno": update.ffaultno,
                "fprocday": update.fprocday,
                "fupddate": update.fupddate,
                "foperator": update.foperator,
                "ferrorno": update.ferrorno,
            })
            return BaseResponse.success()
    except SQLAlchemyError as e:
        # 发生异常时自动回滚
        db.rollback()
        # 记录错误日志
        logging.error(f"数据库错误: {str(e)}")
        # 返回错误响应
        return BaseResponse.error(message="数据库操作失败")
    except Exception as e:
        db.rollback()
        logging.error(f"未知错误: {str(e)}")
        return BaseResponse.error(message="令牌过期")


class EquipmentFaultDelete(BaseModel):
    ferrorno: str = Field(..., description="字典编号")
    feuipmentid: str = Field(..., description="设备编号")


@equipment_fault_router.post("/delete", summary="故障字典删除接口")
def delete_equipment_fault(delete: EquipmentFaultDelete, db: Session = Depends(get_db)):
    try:
        with db.begin():
            sql = "delete from s_ts_equipment_fault where feuipmentid= :feuipmentid  and ferrorno= :ferrorno "
            db.execute(text(sql), {
                "feuipmentid": delete.feuipmentid,
                "ferrorno": delete.ferrorno,
            })
    except SQLAlchemyError as e:
        # 发生异常时自动回滚
        db.rollback()
        # 记录错误日志
        logging.error(f"数据库错误: {str(e)}")
        # 返回错误响应
        return BaseResponse.error(message="数据库操作失败")
    except Exception as e:
        db.rollback()
        logging.error(f"未知错误: {str(e)}")
        return BaseResponse.error(message="令牌过期")
